package com.thinkcoder.service.impl;

import com.thinkcoder.exception.ServiceException;
import com.thinkcoder.exception.UnAuthException;
import com.thinkcoder.mapper.SignMapper;
import com.thinkcoder.redis.RedisUtil;
import com.thinkcoder.service.SignService;
import com.thinkcoder.signutil.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

import static com.thinkcoder.constant.SignConstant.*;


@Service
public class SignServiceImpl implements SignService {

    @Value("${sign.product.name}")
    private String productName;

    @Autowired
    private SignMapper signMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public String getToken(String userId, String timestamp,String sign) {

        checkTimeStamp(timestamp);
        String userPwd=this.signMapper.getUserPwd(userId);
        if("".equals(userPwd)){
            throw new UnAuthException(401,"用户信息不存在");
        }

        //将产品名进行md5加密,并检查用户携带的sign
        String appSecret= MD5Util.md5(productName).toUpperCase();
        String appSign = getSign(userId, userPwd, appSecret, timestamp);
        if(!sign.equals(appSign)){
            throw new UnAuthException(401,"用户验证失败");
        }

        //生成token,并将token存入redis,用户下次请求携带token即可
        String token = UUID.randomUUID().toString();
        redisUtil.set(token,userId,86400);
        return token;
    }


    private void checkTimeStamp(String timestamp){
        long currentTimeMillis = System.currentTimeMillis();
        Long aLong = Long.valueOf(timestamp);

        long l = (currentTimeMillis - aLong) / 1000 * 60;
        if(l>10L){
            throw new ServiceException(500,"请求时间已过10分钟,请重新请求");
        }
    }

    @Override
    public String getSign(String userId,String timestamp){
        checkTimeStamp(timestamp);
        //将产品名进行md5加密,并检查用户携带的sign
        String appSecret= MD5Util.md5(productName).toUpperCase();

        String userPwd=this.signMapper.getUserPwd(userId);
        if("".equals(userPwd)){
            throw new UnAuthException(401,"用户信息不存在");
        }

        return getSign(userId,userPwd,appSecret,timestamp);
    }



    private String getSign(String userId,String userPwd,String appSecret,String timestamp){
        final Map<String,String> params = new HashMap<>(16);
        params.put(SIGN_TIMESTAMP,timestamp);
        params.put(SIGN_USERID,userId);
        params.put(SIGN_USERPWD,userPwd);
        params.put(SIGN_SECRET,appSecret);

        final List<Map.Entry<String,String>> list = sortMap(params);
        StringBuilder stringBuilder = new StringBuilder();
        for(final Map.Entry<String,String> m:list){
            stringBuilder.append(m.getKey()).append(m.getValue());
        }
        String appSign=MD5Util.md5(stringBuilder.toString()).toUpperCase();
        return appSign;
    }


    private List<Map.Entry<String, String>> sortMap(final Map<String, String> map) {
        final List<Map.Entry<String, String>> infos = new ArrayList<Map.Entry<String, String>>(map.entrySet());
        // 重写集合的排序方法：按字母顺序
        Collections.sort(infos, Comparator.comparing(Map.Entry::getKey));
        return infos;
    }
}
